home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / Sources / FWDialog.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  11.6 KB  |  410 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Dialog.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWDIALOG_H
  13. #include "FWDialog.h"
  14. #endif
  15.  
  16. // ----- Framework Layer -----
  17.  
  18. #ifndef FWPART_H
  19. #include "FWPart.h"
  20. #endif
  21.  
  22. #ifndef FWUTIL_H
  23. #include "FWUtil.h"
  24. #endif
  25.  
  26. #ifndef FWFLOWIN_H
  27. #include "FWFloWin.h"
  28. #endif
  29.  
  30. #ifndef FWTABBER_H
  31. #include "FWTabber.h"
  32. #endif
  33.  
  34. #ifndef FWNOTDEF_H
  35. #include "FWNotDef.h"
  36. #endif
  37.  
  38. #ifndef FWIDLE_H
  39. #include "FWIdle.h"
  40. #endif
  41.  
  42. // ----- OS Layer -----
  43.  
  44. #ifndef FWMENU_H
  45. #include "FWMenu.h"
  46. #endif
  47.  
  48. #ifndef FWEVENT_H
  49. #include "FWEvent.h"
  50. #endif
  51.  
  52. #ifndef FWALERT_H
  53. #include "FWAlert.h"
  54. #endif
  55.  
  56. #ifndef SLMixOS_H
  57. #include "SLMixOS.h"
  58. #endif
  59.  
  60. #ifndef FWCFMRES_H
  61. #include "FWCFMRes.h"
  62. #endif
  63.  
  64. // ----- Graphic Includes -----
  65.  
  66. #ifndef FWRECT_H
  67. #include "FWRect.h"
  68. #endif
  69.  
  70. #ifndef FWTXTBOX_H
  71. #include "FWTxtBox.h"
  72. #endif
  73.  
  74. #ifndef FWRECSHP_H
  75. #include "FWRecShp.h"
  76. #endif
  77.  
  78. #ifndef FWPICSHP_H
  79. #include "FWPicShp.h"        
  80. #endif
  81.  
  82. // ----- Foundation Layer -----
  83.  
  84. #ifndef FWEXCDEF_H
  85. #include "FWExcDef.h"
  86. #endif
  87.  
  88. #ifndef FWNOTIFN_H
  89. #include "FWNotifn.h"
  90. #endif
  91.  
  92. // ----- OpenDoc Includes -----
  93.  
  94. #ifndef SOM_ODArbitrator_xh
  95. #include <Arbitrat.xh>
  96. #endif
  97.  
  98. #ifndef SOM_ODFocusSet_xh
  99. #include <FocusSet.xh>
  100. #endif
  101.  
  102. #ifndef SOM_ODSession_xh
  103. #include <ODSessn.xh>
  104. #endif
  105.  
  106. //========================================================================================
  107. // Runtime Informations
  108. //========================================================================================
  109.  
  110. #ifdef FW_BUILD_MAC
  111. #pragma segment fwpart2
  112. #endif
  113.  
  114. FW_DEFINE_CLASS_M2(FW_CDialogFrame, FW_CFrame, FW_MReceiver)
  115. FW_DEFINE_AUTO(FW_CDialogFrame)
  116.  
  117. //========================================================================================
  118. //  class FW_CDialogFrame
  119. //========================================================================================
  120.  
  121. //----------------------------------------------------------------------------------------
  122. // FW_CDialogFrame::FW_CDialogFrame
  123. //----------------------------------------------------------------------------------------
  124. FW_CDialogFrame::FW_CDialogFrame(Environment* ev, 
  125.                                 ODFrame* odFrame, 
  126.                                 FW_CPresentation* presentation, 
  127.                                 FW_CPart* part,
  128.                                 FW_ResourceId id)
  129.     : FW_CFrame(ev, odFrame, presentation, part, id),
  130.     FW_MReceiver(),
  131.     fDefaultButton(NULL),
  132.     fCancelButton(NULL)
  133. {
  134.     // Add a ViewTabber and an idler by default 
  135.     fViewTabber = new FW_CViewTabber(ev, this); 
  136.  
  137.     fIdler = FW_NEW(FW_CIdler, (this, 15));
  138.     fIdler->RegisterIdle(ev);            
  139.     
  140.     fIsModal = TRUE;        // [LSD] see non-modal dialogs later
  141.  
  142.     FW_END_CONSTRUCTOR
  143. }
  144.  
  145. //----------------------------------------------------------------------------------------
  146. // FW_CDialogFrame::~FW_CDialogFrame
  147. //----------------------------------------------------------------------------------------
  148.  
  149. FW_CDialogFrame::~FW_CDialogFrame()
  150. {
  151.     FW_START_DESTRUCTOR
  152.     
  153.     delete fIdler;
  154.     fIdler = NULL;
  155.  
  156.     // fViewTabber event handler is deleted automatically
  157. }
  158.  
  159. //----------------------------------------------------------------------------------------
  160. // FW_CDialogFrame::PrivButtonAttached
  161. //----------------------------------------------------------------------------------------
  162.  
  163. void FW_CDialogFrame::PrivButtonAttached(Environment* ev, FW_CButton* button)
  164. {
  165.     if (button->GetMessage(ev) == FW_kDefaultButtonMsg)
  166.     {
  167.         fDefaultButton = PrivSetDismissButton(ev, button, FW_kDefaultButtonMsg, fDefaultButton);
  168.     }
  169.     else if (button->GetMessage(ev) == FW_kCancelButtonMsg)
  170.     {
  171.         fCancelButton = PrivSetDismissButton(ev, button, FW_kCancelButtonMsg, fCancelButton);
  172.     }
  173. }
  174.  
  175. //----------------------------------------------------------------------------------------
  176. // FW_CDialogHandler::SetDefaultButton
  177. //----------------------------------------------------------------------------------------
  178.  
  179. void FW_CDialogFrame::SetDefaultButton(Environment* ev, ODID id)
  180. {
  181.     // Use this method only if you want to change or remove an existing default button.
  182.     // (Use id = 0 to remove an existing default button)
  183.     // The dialog's default button is automatically set when you use FW_kDefaultButtonMsg
  184.     // for the button's message value (either in code or resources)
  185.     
  186.     FW_CButton* button = NULL;
  187.     if (id != 0)
  188.     {
  189.         button = FW_DYNAMIC_CAST(FW_CButton, FindViewById(ev, id));
  190.         FW_ASSERT(button);
  191.     }
  192.  
  193.     fDefaultButton = PrivSetDismissButton(ev, button, FW_kDefaultButtonMsg, fDefaultButton);
  194. }
  195.  
  196. //----------------------------------------------------------------------------------------
  197. // FW_CDialogFrame::SetCancelButton
  198. //----------------------------------------------------------------------------------------
  199.  
  200. void FW_CDialogFrame::SetCancelButton(Environment* ev, ODID id)
  201. {
  202.     // Use this method only if you want to change or remove an existing cancel button.
  203.     // (Use id = 0 to remove an existing cancel button)
  204.     // The dialog's cancel button is automatically set when you use FW_kCancelButtonMsg
  205.     // for the button's message value (either in code or resources)
  206.     
  207.     FW_CButton* button = NULL;
  208.     if (id != 0)
  209.     {
  210.         button = FW_DYNAMIC_CAST(FW_CButton, FindViewById(ev, id));
  211.         FW_ASSERT(button);
  212.     }
  213.     
  214.     fCancelButton = PrivSetDismissButton(ev, button, FW_kCancelButtonMsg, fCancelButton);
  215. }
  216.  
  217. //----------------------------------------------------------------------------------------
  218. // FW_CDialogHandler::PrivSetDismissButton
  219. //----------------------------------------------------------------------------------------
  220.  
  221. FW_CButton* FW_CDialogFrame::PrivSetDismissButton(Environment* ev, FW_CButton* newButton, FW_Message message, FW_CButton* prevButton)
  222. {
  223.     if (prevButton) {
  224.         // Remove outline
  225.         if (message == FW_kDefaultButtonMsg)
  226.             prevButton->SetButtonKind(ev, FW_kPushButton);    
  227.         
  228.         // Remove connection
  229.         prevButton->RemoveReceiver(this, FW_CInterest(prevButton, message));
  230.         // Reset button's message
  231.         prevButton->SetMessage(ev, FW_kNullMsg);
  232.         
  233.         prevButton = NULL;
  234.     }
  235.     
  236.     if (newButton) {
  237.         // Add outline
  238.         if (message == FW_kDefaultButtonMsg)
  239.             newButton->SetButtonKind(ev, FW_kDefaultPushButton);        
  240.         // Set the button's message & connect dialog
  241.         newButton->SetMessage(ev, message);
  242.         newButton->LinkControlTo(ev, this);
  243.     }
  244.     
  245.     return newButton;
  246. }
  247.  
  248. //----------------------------------------------------------------------------------------
  249. //    FW_CDialogFrame::HandleNotification
  250. //----------------------------------------------------------------------------------------
  251.  
  252. void FW_CDialogFrame::HandleNotification(Environment* ev, const FW_CNotification& notification)
  253. {
  254.     // ---- close the dialog on OK or Cancel ----
  255.     if (notification.GetMessage() == FW_kDefaultButtonMsg ||
  256.         notification.GetMessage() == FW_kCancelButtonMsg)
  257.     {
  258.         GetWindow(ev)->CloseAndRemove(ev);
  259.         //    ATTENTION: The whole window is gone at this point. So don't try to do
  260.         //    anything after this point
  261.     }
  262. }
  263.  
  264. //----------------------------------------------------------------------------------------
  265. // FW_CDialogFrame::NewModalDialog
  266. //----------------------------------------------------------------------------------------
  267.  
  268. FW_CDialogFrame* FW_CDialogFrame::NewModalDialog(Environment* ev, 
  269.                                             FW_CPart* part, 
  270.                                             FW_CPresentation* presentation,
  271.                                             const FW_CPoint& size, 
  272.                                             const FW_CPoint& position, 
  273.                                             FW_WindowStyle style, 
  274.                                             const FW_CString& windowTitle)
  275. {
  276.     // [LSD] todo: add checking on authorized window styles.  See FWWindow.k            
  277.     FW_WindowStyle    winStyle = FW_kModalDialog | style;
  278.  
  279.     // Create dialog window (which in turn will create a dialog frame through the
  280.     // part's NewFrame method, will create a facet and will create the subviews)
  281.     FW_CWindow* dialogWindow = new FW_CWindow(ev, part, 
  282.                                             NULL,         // no parent frame
  283.                                             FALSE,         // Dialogs are not persistent
  284.                                             FW_CPart::gViewAsFrameToken,
  285.                                             presentation,
  286.                                             windowTitle,
  287.                                             size,
  288.                                             position,
  289.                                             winStyle);
  290.     
  291.     // Use standard position
  292.     if ((winStyle & FW_kStandardDialogPosition) != 0)
  293.     {
  294.         FW_PlatformError error;
  295.         ::FW_PositionModalDialog(dialogWindow->GetPlatformWindow(ev), &error);
  296.         FW_FailOnError(error);
  297.     }
  298.     
  299.     // Get the dialog frame from the window and try to open it
  300.     FW_CAcquiredODWindow aqODDialog = dialogWindow->AcquireODWindow(ev);
  301.     ODFrame* odFrame = aqODDialog->GetRootFrame(ev);
  302.     FW_CDialogFrame* dialogFrame = (FW_CDialogFrame *)FW_CFrame::ODtoFWFrame(ev, odFrame);
  303.     FW_Boolean isMoveable = winStyle & FW_kHasCaption ? true : false;
  304.     
  305.     if (dialogFrame->TryModalFocus(ev, odFrame, isMoveable) == FALSE) {        
  306.         // modal focus could not be granted    
  307.         delete dialogWindow;    
  308.         return NULL;    
  309.     }
  310.     return dialogFrame;
  311. }
  312.  
  313. //----------------------------------------------------------------------------------------
  314. // FW_CDialogFrame::NewAndShowModalDialog
  315. //----------------------------------------------------------------------------------------
  316. // Same as NewModalDialog but show the window too. Useful when no initialization is needed
  317.  
  318. FW_CDialogFrame* FW_CDialogFrame::NewAndShowModalDialog(Environment* ev,  
  319.                                     FW_CPart* part, FW_CPresentation* presentation,
  320.                                     const FW_CPoint& size, const FW_CPoint& position, 
  321.                                     FW_WindowStyle style, const FW_CString& windowTitle)
  322. {
  323.     FW_CDialogFrame* dialogFrame = NewModalDialog(ev, part, presentation, size, position,
  324.                                                         style, windowTitle);
  325.     
  326.     if (dialogFrame != NULL)
  327.     {
  328.         dialogFrame->GetWindow(ev)->Show(ev);
  329.     }
  330.     return dialogFrame;
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. // FW_CDialogFrame::TryModalFocus
  335. //----------------------------------------------------------------------------------------
  336.  
  337. FW_Boolean FW_CDialogFrame::TryModalFocus(Environment* ev, ODFrame* odFrame, FW_Boolean isMoveable)
  338. {
  339.     ODSession* session = GetPart(ev)->GetSession(ev);
  340.     
  341.     if (session->GetArbitrator(ev)->RequestFocus(ev, FW_CPart::gModalFocusToken, odFrame))
  342.     {
  343.         // Add modal focus to the frame's focus set
  344.         GetFocusSet(ev)->Add(ev, FW_CPart::gModalFocusToken);
  345.         
  346.         // Hide floating windows
  347.         FW_CFloatingWindow::HideShowFloatingWindows(ev, session->GetWindowState(ev), FALSE);
  348.         
  349.         // Disable the whole menubar
  350.         // (Edit menu will be enabled later if dialog contains an active text-edit) 
  351.         if (fIsModal)
  352.             GetPart(ev)->PrivEnableMenuBar(ev, FALSE, isMoveable);            
  353.     
  354.         // Select the first target
  355.         fViewTabber->Tab(ev, this);
  356.         
  357.         return TRUE;
  358.     }
  359.     return FALSE;
  360. }
  361.  
  362. //----------------------------------------------------------------------------------------
  363. //    FW_CDialogFrame::FrameRemoved
  364. //----------------------------------------------------------------------------------------
  365.  
  366. void FW_CDialogFrame::FrameRemoved(Environment* ev, FW_Boolean toStorage)
  367. {
  368.     // ----- re-enable the menubar after Modal dialog
  369.     if (fIsModal)
  370.         GetPart(ev)->PrivEnableMenuBar(ev, true, false);
  371.  
  372.     // ----- Call inherited -----
  373.     FW_CFrame::FrameRemoved(ev, toStorage);    
  374. }
  375.  
  376. //----------------------------------------------------------------------------------------
  377. // FW_CDialogFrame::DoVirtualKey
  378. //----------------------------------------------------------------------------------------
  379.  
  380. FW_Boolean FW_CDialogFrame::DoVirtualKey (Environment* ev, const FW_CVirtualKeyEvent & event)
  381. {
  382.     FW_CButton* button = NULL;
  383.     
  384.     switch (event.GetKeyCode(ev)) {
  385.     case FW_kVKEnter:
  386.     case FW_kVKReturn:
  387.         button = GetDefaultButton(ev);
  388.         break;
  389.     
  390.     case FW_kVKEscape:    
  391.         button = GetCancelButton(ev);
  392.         break;
  393.     
  394.     default:
  395.         if (event.IsCommandPeriod(ev)) {
  396.             button = GetCancelButton(ev);
  397.         }
  398.         break;
  399.     }
  400.     
  401.     if (button) {
  402.         button->SimulateButtonPressed(ev);
  403.         return TRUE;
  404.     }
  405.     // returning FALSE will propagate the same key as a CharKeyEvent on the Mac
  406.     return FALSE;    
  407. }
  408.  
  409.  
  410.